"""
Case Type   : WDR
Case Name   : 开启数据库监控快照功能，指定生成节点级别（node）报告，node_name不一致
Create At   : 2023.1.6
Owner       : @haomeng802
Description :
    1、修改参数，开启快照功能
    2、使用默认系统库，查看当前快照数据
    3、手动生成快照，并查看快照
    4、指定生成html格式的WDR报告
    5、查看当前节点名称
    6、向报告中写入数据，node_name非当前节点
    7、清理环境，恢复参数
Expect      :
    1、开启快照功能成功
    2、查看快照数据成功
    3、手动生成快照成功，查看成功(存在两条以上数据)
    4、生成报告成功
    5、查看当前节点名称成功
    6、写入数据失败，node_name无效
    7、清理环境成功，恢复参数成功
History     :
    modified by @haomeng802 at 2023/1/31:优化用例
    modified by @haomeng at 2025/03/04:优化用例增加等待时长避免因环境性能问题导致快照查看失败
"""

import os
import unittest

from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class WDR(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.sh_pri = CommonSH('PrimaryDbUser')
        self.user_node = Node('PrimaryDbUser')
        self.constant = Constant()
        self.config_wdr = "enable_wdr_snapshot"
        self.table = 'snapshot.snapshot'
        self.report_path = os.path.join(macro.DB_INSTANCE_PATH,
                                        'wdr_020.html')

    def test_wdr(self):
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        text = '-----step1:检查参数，修改参数配置;expect:成功-----'
        self.log.info(text)

        check_wdr = self.sh_pri.execut_db_sql(f'''show {self.config_wdr};''')
        self.log.info(check_wdr)
        if 'on' != check_wdr.splitlines()[-2].strip():
            self.sh_pri.execute_gsguc('reload',
                                      self.constant.GSGUC_SUCCESS_MSG,
                                      f'''{self.config_wdr} = "on"''')

        param = self.sh_pri.execut_db_sql(f'''show {self.config_wdr};''')
        self.assertEqual('on', param.splitlines()[-2].strip(),
                         '执行失败:' + text)

        text = '-----step2:查看快照数据;expect:查看快照数据成功-----'
        self.log.info(text)

        select_cmd = f'''select pg_sleep(10);select count(*) from {self.table};'''
        show_res1 = self.sh_pri.execut_db_sql(select_cmd, dbname='postgres')
        self.log.info(show_res1)
        self.assertEqual('1', show_res1.splitlines()[-2].strip(),
                         '执行失败:' + text)

        text = '-----step3:手动生成快照;expect:生成快照成功-----'
        self.log.info(text)

        create_snap = f'''select create_wdr_snapshot();
            select pg_sleep(15);
            select count(*) from {self.table};'''
        self.log.info(create_snap)
        create_res = self.sh_pri.execut_db_sql(create_snap, dbname='postgres')
        self.log.info(create_res)
        self.assertEqual('2', create_res.splitlines()[-2].strip(),
                         '执行失败:' + text)

        text = '-----step4:指定生成html格式的WDR报告;expect:生成报告成功-----'
        self.log.info(text)

        report_cmd = f'''\o {self.report_path}'''
        self.log.info(report_cmd)
        report_res = self.sh_pri.execut_db_sql(report_cmd, dbname='postgres')
        self.log.info(report_res)
        check_res = self.user_node.sh(
            f'''ls {macro.DB_INSTANCE_PATH}''').result()
        self.log.info(check_res)
        self.assertIn('wdr_020.html', check_res, '执行失败' + text)

        text = '-----step5:查看当前节点名称;expect:查看成功-----'
        self.log.info(text)
        check_node = f'''select node_name from pg_node_env;'''
        node = self.sh_pri.execut_db_sql(check_node, dbname='postgres')
        self.log.info(node)

        text = '-----step5:向报告中写入数据，node_name非当前节点名称;' \
               'expect:写入数据失败,node_name无效-----'
        self.log.info(text)

        error_node = node + 'error'
        snap_id = f'''select snapshot_id from {self.table};'''
        snap_id_res = self.sh_pri.execut_db_sql(snap_id, dbname='postgres')
        self.log.info(snap_id_res)
        start_id = snap_id_res.splitlines()[2].strip()
        end_id = snap_id_res.splitlines()[-2].strip()

        snap_sql = f'''select generate_wdr_report({start_id}, {end_id}, 
            'all', 'node', '{error_node}');'''
        node_res = self.sh_pri.execut_db_sql(snap_sql, dbname='postgres')
        self.log.info(node_res)
        self.assertIn('ERROR', node_res, '执行失败:' + text)

    def tearDown(self):
        text = '-----step6:清理环境,还原参数;expect:成功-----'
        self.log.info(text)

        drop_snapshot = f'''truncate table {self.table};
            select count(*) from {self.table};'''
        self.log.info(drop_snapshot)
        drop_res = self.sh_pri.execut_db_sql(drop_snapshot, dbname='postgres')
        self.log.info(drop_res)

        drop_html = f'''rm -rf {self.report_path};
            ls {macro.DB_INSTANCE_PATH}'''
        drop_html_res = self.user_node.sh(drop_html).result()
        self.log.info(drop_html_res)

        recov_wdr = self.sh_pri.execut_db_sql(f'''show {self.config_wdr};''')
        self.log.info(recov_wdr)
        if 'off' != recov_wdr.splitlines()[-2].strip():
            self.sh_pri.execute_gsguc('reload',
                                      self.constant.GSGUC_SUCCESS_MSG,
                                      f'''{self.config_wdr} = "off"''')

        param1 = self.sh_pri.execut_db_sql(f'''show {self.config_wdr};''')
        self.log.info(param1)

        self.assertEqual('off', param1.splitlines()[-2].strip(), '参数恢复成功')
        self.assertNotIn('wdr_020.html', drop_html_res, '文件清理成功')
        self.assertEqual('0', drop_res.splitlines()[-2].strip(),
                         '执行失败:' + text)
        self.log.info(f'----{os.path.basename(__file__)} end-----')
